
Submitted by: Student
From school: A High School
In this notebook, I will be comparing the strongest 15 Pokémon in the categories: "attack", "sp_attack", "defense", "sp_defense", "hp", and "speed" with each other, along displaying these attributes against regular Pokémon compared to legendary Pokémon! As someone new to CS and data science, this isn't the most elaborate hackathon submission. Nonetheless, enjoy my findings!
# Import libraries and data
import pandas as pd
import plotly.express as px
from IPython.display import YouTubeVideo
pokemon = pd.read_csv('https://raw.githubusercontent.com/callysto/data-files/main/hackathon/pokemon.csv')
pokemon
| abilities | against_bug | against_dark | against_dragon | against_electric | against_fairy | against_fight | against_fire | against_flying | against_ghost | ... | percentage_male | pokedex_number | sp_attack | sp_defense | speed | type1 | type2 | weight_kg | generation | is_legendary | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | ['Overgrow', 'Chlorophyll'] | 1.00 | 1.0 | 1.0 | 0.5 | 0.5 | 0.5 | 2.0 | 2.0 | 1.0 | ... | 88.1 | 1 | 65 | 65 | 45 | grass | poison | 6.9 | 1 | 0 |
| 1 | ['Overgrow', 'Chlorophyll'] | 1.00 | 1.0 | 1.0 | 0.5 | 0.5 | 0.5 | 2.0 | 2.0 | 1.0 | ... | 88.1 | 2 | 80 | 80 | 60 | grass | poison | 13.0 | 1 | 0 |
| 2 | ['Overgrow', 'Chlorophyll'] | 1.00 | 1.0 | 1.0 | 0.5 | 0.5 | 0.5 | 2.0 | 2.0 | 1.0 | ... | 88.1 | 3 | 122 | 120 | 80 | grass | poison | 100.0 | 1 | 0 |
| 3 | ['Blaze', 'Solar Power'] | 0.50 | 1.0 | 1.0 | 1.0 | 0.5 | 1.0 | 0.5 | 1.0 | 1.0 | ... | 88.1 | 4 | 60 | 50 | 65 | fire | NaN | 8.5 | 1 | 0 |
| 4 | ['Blaze', 'Solar Power'] | 0.50 | 1.0 | 1.0 | 1.0 | 0.5 | 1.0 | 0.5 | 1.0 | 1.0 | ... | 88.1 | 5 | 80 | 65 | 80 | fire | NaN | 19.0 | 1 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 796 | ['Beast Boost'] | 0.25 | 1.0 | 0.5 | 2.0 | 0.5 | 1.0 | 2.0 | 0.5 | 1.0 | ... | NaN | 797 | 107 | 101 | 61 | steel | flying | 999.9 | 7 | 1 |
| 797 | ['Beast Boost'] | 1.00 | 1.0 | 0.5 | 0.5 | 0.5 | 2.0 | 4.0 | 1.0 | 1.0 | ... | NaN | 798 | 59 | 31 | 109 | grass | steel | 0.1 | 7 | 1 |
| 798 | ['Beast Boost'] | 2.00 | 0.5 | 2.0 | 0.5 | 4.0 | 2.0 | 0.5 | 1.0 | 0.5 | ... | NaN | 799 | 97 | 53 | 43 | dark | dragon | 888.0 | 7 | 1 |
| 799 | ['Prism Armor'] | 2.00 | 2.0 | 1.0 | 1.0 | 1.0 | 0.5 | 1.0 | 1.0 | 2.0 | ... | NaN | 800 | 127 | 89 | 79 | psychic | NaN | 230.0 | 7 | 1 |
| 800 | ['Soul-Heart'] | 0.25 | 0.5 | 0.0 | 1.0 | 0.5 | 1.0 | 2.0 | 0.5 | 1.0 | ... | NaN | 801 | 130 | 115 | 65 | steel | fairy | 80.5 | 7 | 1 |
801 rows × 41 columns
Column Descriptions:
Pokémon are always used in fighting tournaments. Let's create a chart that displays the top 15 Pokémon with the strongest Base Attack, accompanied by their Base Special Attack!
pokemon_by_attack = pokemon[["name", "attack", "sp_attack"]]
pokemon_by_attack = pokemon_by_attack.sort_values(by=["attack"], ascending=False)
pokemon_by_attack.head(15)
| name | attack | sp_attack | |
|---|---|---|---|
| 213 | Heracross | 185 | 40 |
| 797 | Kartana | 181 | 59 |
| 382 | Groudon | 180 | 150 |
| 383 | Rayquaza | 180 | 180 |
| 444 | Garchomp | 170 | 120 |
| 408 | Rampardos | 165 | 65 |
| 353 | Banette | 165 | 93 |
| 474 | Gallade | 165 | 65 |
| 247 | Tyranitar | 164 | 95 |
| 288 | Slaking | 160 | 95 |
| 718 | Diancie | 160 | 160 |
| 485 | Regigigas | 160 | 80 |
| 719 | Hoopa | 160 | 170 |
| 256 | Blaziken | 160 | 130 |
| 126 | Pinsir | 155 | 65 |
Let's visualize the chart by turning it into a bar graph!
px.bar(pokemon_by_attack.head(15), x="name", y=["attack", "sp_attack"], barmode="group", title="Top 15 Strongest Pokémon by Attack, Accompanied by Their SP Attack")
Interestingly, Rayquaza has the most powerful Base Special Attack despite only having the 4th strongest Base Attack. Furthermore, Heracross, having the strongest Base Attack out of all Pokémon, had the weakest Base Special Attack within the top 15 Pokémon on the graph.
Now let's graph all Pokémon (within the dataset) based on their Base Attack and Base SP Attack. Furthermore, let's identify which Pokémon are legendary!
px.scatter(pokemon, x='attack', y='sp_attack', color="is_legendary", hover_data=['name'], title='Pokémon Attack vs SP Attack')
A Pokémon can't participate in a true tournament without some form of defense. Let's create a new chart that displays the top 15 Pokémon with the strongest Base Defense, accompanied by their Base Special Defense!
pokemon_by_defense = pokemon[["name", "defense", "sp_defense"]]
pokemon_by_defense = pokemon_by_defense.sort_values(by=["defense"], ascending=False)
pokemon_by_defense.head(15)
| name | defense | sp_defense | |
|---|---|---|---|
| 305 | Aggron | 230 | 80 |
| 212 | Shuckle | 230 | 230 |
| 207 | Steelix | 230 | 95 |
| 376 | Regirock | 200 | 100 |
| 712 | Avalugg | 184 | 46 |
| 90 | Cloyster | 180 | 45 |
| 79 | Slowbro | 180 | 80 |
| 410 | Bastiodon | 168 | 138 |
| 94 | Onix | 160 | 45 |
| 382 | Groudon | 160 | 90 |
| 747 | Toxapex | 152 | 142 |
| 679 | Doublade | 150 | 49 |
| 378 | Registeel | 150 | 150 |
| 247 | Tyranitar | 150 | 120 |
| 375 | Metagross | 150 | 110 |
Repeating what we did with the strongest Pokémon attacks, let's do the same with the strongest Pokémon defense and comparing these variables on all Pokémon with a scatter graph!
px.bar(pokemon_by_defense.head(15), x="name", y=["defense", "sp_defense"], barmode="group", title="Top 15 Strongest Pokémon by Defense, Accompanied by Their SP Defense")
px.scatter(pokemon, x='defense', y='sp_defense', color="is_legendary", hover_data=['name'], title='Pokémon Defense vs SP Defense')
Unlike the first scatter graph, where the difference between legendary Pokémon and regular Pokémon was wider in regards to Base Attacks and Base Special Attacks, the gap is a lot closer when it comes to Base Defense and Base Special Defense
Repeating what we did in the last 2 comparisons, let's finally see who the best Pokémon are when it comes to HP and Speed!
pokemon_by_remainder = pokemon[["name", "hp", "speed"]]
pokemon_by_remainder = pokemon_by_remainder.sort_values(by=["hp"], ascending=False)
pokemon_by_remainder.head(15)
| name | hp | speed | |
|---|---|---|---|
| 241 | Blissey | 255 | 55 |
| 112 | Chansey | 250 | 50 |
| 798 | Guzzlord | 223 | 43 |
| 717 | Zygarde | 216 | 85 |
| 201 | Wobbuffet | 190 | 33 |
| 320 | Wailord | 170 | 60 |
| 593 | Alomomola | 165 | 65 |
| 142 | Snorlax | 160 | 30 |
| 486 | Giratina | 150 | 90 |
| 425 | Drifblim | 150 | 80 |
| 288 | Slaking | 150 | 100 |
| 296 | Hariyama | 144 | 50 |
| 39 | Wigglytuff | 140 | 45 |
| 790 | Solgaleo | 137 | 97 |
| 791 | Lunala | 137 | 97 |
px.bar(pokemon_by_remainder.head(15), x="name", y=["hp", "speed"], barmode="group", title="Top 15 Strongest Pokémon by HP, Accompanied by Their Speed")
Not surprisingly, there seems to be somewhat of a correlation between a Pokémons HP, and their Speed. This may be because a Pokémon with more HP would be more heavy and typically slower than other types of Pokémon. Such a hypothesis is supported with Pokémon like Blissey, Chansey, and Guzzlord having high HP but low Speed.
px.scatter(pokemon, x='hp', y='speed', color="is_legendary", hover_data=['name'], title='Pokémon HP vs Speed')